// 不足两位补 0
const fillTimeGap = (time: number) => (time < 10 ? `0${time}` : `${time}`)

/** 输入 string 或 Date, 返回 Date 对象 */
const getDate = (input: string | Date) => {
  if (input instanceof Date) {
    return input
  }
  if (input.includes('T')) {
    return new Date(input)
  }
  // todo 根据字符串长度判断不是很健壮 有时间专门优化一下不同浏览器的兼容
  if (input.includes('-') && input.length >= 8) {
    return new Date(input.replace(/-/g, '/'))
  }
  return new Date(input)
}

/** 格式化日期 */
export function formatDate(input: string | Date = new Date(), timeFormat = 'YYYY-MM-DD hh:mm:ss') {
  const weekArr = ['日', '一', '二', '三', '四', '五', '六']
  const date = getDate(input)

  const Y = date.getFullYear()
  const M = date.getMonth() + 1
  const MM = fillTimeGap(M)
  const D = date.getDate()
  const DD = fillTimeGap(date.getDate())
  const W = weekArr[date.getDay()]
  const h = date.getHours()
  const hh = fillTimeGap(date.getHours())
  const m = date.getMinutes()
  const mm = fillTimeGap(date.getMinutes())
  const s = date.getSeconds()
  const ss = fillTimeGap(date.getSeconds())

  return timeFormat
    .replace('YYYY', Y.toString())
    .replace(/M{2}/, MM)
    .replace(/M/, M.toString())
    .replace(/D{2}/, DD)
    .replace(/D/, D.toString())
    .replace(/W{1,2}/, W)
    .replace(/h{2}/, hh)
    .replace(/h/, h.toString())
    .replace(/m{2}/, mm)
    .replace(/m/, m.toString())
    .replace(/s{2}/, ss)
    .replace(/s/, s.toString())
}

// 获取n年前的日期
export function getYearsAgoDate(
  n: number,
  date: string | Date = new Date(),
  timeFormat = 'YYYY-MM-DD',
) {
  date = getDate(date)
  date.setFullYear(date.getFullYear() - n)
  return formatDate(date, timeFormat)
}
// 获取n月前的日期
export function getMonthsAgoDate(
  n: number,
  date: string | Date = new Date(),
  timeFormat = 'YYYY-MM-DD',
) {
  date = getDate(date)
  date.setMonth(date.getMonth() - n)
  return formatDate(date, timeFormat)
}
// 获取n天前的日期
export function getDaysAgoDate(
  n: number,
  date: string | Date = new Date(),
  timeFormat = 'YYYY-MM-DD',
) {
  date = getDate(date)
  const milliseconds = date.getTime() - 1000 * 60 * 60 * 24 * n
  const finalDate = new Date(milliseconds)
  return formatDate(finalDate, timeFormat)
}
/**
 * 比较左边日期和右边日期
 * @return {1, 0, -1} 1: leftDate > rightDate / -1: leftDate < rightDate / 0: leftDate = rightDate
 * rightDate 不传默认取当前时间
 */
type Exclude<T> = T extends Date | string ? number : undefined
export const compareDate = <TL extends Date | string, TR extends Date | string, T extends TL | TR>(
  leftDate: TL,
  rightDate?: TR,
): Exclude<T> => {
  if (!leftDate) return void 0 as Exclude<T>
  let left = getDate(leftDate)
  let right = rightDate ? getDate(rightDate) : new Date()
  const result = left.getTime() - right.getTime()
  return (result > 0 ? 1 : result < 0 ? -1 : 0) as Exclude<T>
}

export function getTimeDistance(date1: string, date2: string) {
  var date3 = getDate(date2).getTime() - getDate(date1).getTime() //时间差的毫秒数
  //计算出相差天数
  var days = Math.floor(date3 / (24 * 3600 * 1000))

  //计算出小时数
  var leave1 = date3 % (24 * 3600 * 1000) //计算天数后剩余的毫秒数
  var hours = Math.floor(leave1 / (3600 * 1000))
  //计算相差分钟数
  var leave2 = leave1 % (3600 * 1000) //计算小时数后剩余的毫秒数
  var minutes = Math.floor(leave2 / (60 * 1000))
  //计算相差秒数
  var leave3 = leave2 % (60 * 1000) //计算分钟数后剩余的毫秒数
  var seconds = Math.round(leave3 / 1000)
  return {
    days,
    hours,
    minutes,
    seconds,
  }
}
